let { Service } = require('egg')
const { mysql } = require('../../config/plugin')
const countTime = require('../utils/time.js')


class ReservationService extends Service {

  // 发起预约
  async createRes(dayTimeId, userId, askReason, type, isExamine) {
    let { mysql } = this.app
    // 如果因为某些因素造成当前空间满的，申请人数是0，此时可以将类型更新为0
    let timeInfo = await mysql.get('daytime', { timeId: dayTimeId })
    // if (timeInfo.tVolume == timeInfo.baseVolume && timeInfo.nowCount == 0) {
    //   let options = {
    //     where: { timeId: dayTimeId }
    //   }
    //   await mysql.update('daytime', { tStatus: 0 }, options)
    // }

    let status
    if (isExamine == 0) {
      // 无需审核，自动通过
      status = 2
    } else if (isExamine == 1) {
      // 需要审核
      status = 1
    }
    
    let createTime = new Date().getTime()
    // 这样就可以预约了
    let res = await mysql.insert('reservation', { userId, dayTimeId, askReason, rejectReason: "", status, createTime, type, isExamine })
    // console.log(res);
    if (res.affectedRows === 1) {
      // 1.根据是否需要审核来更新预约记录的信息
      // 如果无需审核同时要将相应的可预约时间段的容量-1

      let options1 = {
        where: { timeId: dayTimeId }
      }
      if (isExamine == 0) {
        if(type == 1){
          let tVolume = timeInfo.tVolume
          tVolume = tVolume - 1
          let sql = `update daytime set tVolume = ? where timeId = ?`
          let res = await mysql.query(sql, [tVolume, dayTimeId])
        }
        //  课堂预约，需要标记当前申请人数
        if(type==0){
          let nowCount = timeInfo.nowCount
          nowCount = nowCount + 1
          // let res1 = await mysql.update('daytime', { nowCount }, options1)
          let sql = `update daytime set nowCount = ? where timeId = ?`
          let res = await mysql.query(sql, [nowCount, dayTimeId])
        }


        // let res1 = await mysql.update('daytime', { tVolume: 123 }, options1)
 
      } else if (isExamine ==1) {
        // 需要审核

                  let nowCount = timeInfo.nowCount
                  nowCount = nowCount + 1
                  // let res1 = await mysql.update('daytime', { nowCount }, options1)
                  let sql = `update daytime set nowCount = ? where timeId = ?`
                  let res = await mysql.query(sql, [nowCount, dayTimeId])

      }
      // 第一个预约的用户一定会改变这条记录的预约类型，后边的都是课堂或者个人，所以每次都改一次预约类型应该没问题
      // type 为0是课堂预约 type 为1是个人预约
      if (type == 0) {
        await mysql.update('daytime', { tStatus: 1 }, options1)

      } else if (type == 1) {
        await mysql.update('daytime', { tStatus: 2 }, options1)

      }

      return "预约申请成功"
    } else {
      return "预约申请失败"
    }
  }
  // 判断时间冲突
  async noConflict(userId, start, end, dateTime) {
    let { mysql } = this.app
    start = countTime(start)
    end = countTime(end)
    // 查询用户的当日所有预约记录
    let sql = `select * from reservation where userId = ? and dayTimeId in (select timeId from daytime where dateTime = ?)`
    let reList = await mysql.query(sql, [userId, dateTime])
    // 只要申请成功的和待审核的
    let arr = [...reList]
    let arr1 = []
    arr.forEach((item,index)=>{
      if(item.status==1||item.status==2){
        arr1.push(item)
      }
    })
    arr = [...arr1]
    let isConf = false
    for (let i = 0; i < arr.length; i++) {
      // let timeInfo = await mysql.get('')
      let sql = `select * from timeoption where timeId in (select timeOpId from daytime where timeId in (select dayTimeId from reservation where reservationId = ?))`

      let timeoption = await mysql.query(sql, [arr[i].reservationId])
      arr[i].start = countTime(timeoption[0].start)
      arr[i].end = countTime(timeoption[0].end)

    }


    for (let i = 0; i < arr.length; i++) {
      if (arr[i].start == start && arr[i].end == end) {
        isConf = true
      }

      if (start > arr[i].start && start < arr[i].end) {
        isConf = true
      }

      if (end > arr[i].start && end < arr[i].end) {
        isConf = true
      }
      if (start < arr[i].start && end > arr[i].end) {
        isConf = true
      }

    }
    let obj = {

    }
    if (isConf) {
      obj.isConf = true
      obj.message = "当前预约时间与您的其他预约相冲突"
      return obj
    } else {
      obj.isConf = false
      obj.message = "未发生时间冲突"
      return obj
    }

  }
  // 判断其他剩余实验室 (核心1)
  async canIRes(tStatus, typeId, resType, dateTime, start, end) {
    let { mysql } = this.app
    let obj = {}

    tStatus = parseInt(tStatus)

    typeId = parseInt(typeId)
    if (tStatus == 0) {
      // resType是我想预约的类型
      // 暂时没有被预约的时候，如果是个人预约再查，不是个人预约就无需判断
      if (resType == 1) {
        //  查出同一类别的当日可预约时间段
        let sql = `select  * from dayTime where timeOpId in (select timeId from timeoption where laboratoryId in (select laboratoryId from laboratory where typeId = ?))`
        let sameTypeList = await mysql.query(sql, [typeId])

        // 遍历找出同一天、个人预约、还有剩余空间的
        let arr = [...sameTypeList]
        let arr1 = []
        for (let i = 0; i < arr.length; i++) {
          if (arr[i].tStatus == 2 && (arr[i].tVolume > 0 && (arr[i].baseVolume > arr[i].tVolume||arr[i].baseVolume == arr[i].tVolume)) && arr[i].dateTime == dateTime) {
            arr1.push(arr[i])
          }
        }


        let ishave = false
        // 分别查出他们的时间段，然后赋值给他们
        for (let i = 0; i < arr1.length; i++) {
          let timeoption = await mysql.get('timeoption', { timeId: arr1[i].timeOpId })
          if (timeoption.start == start && timeoption.end == end) {
            obj.timeId = arr1[i].timeId
            obj.message = "存在还有没有约完的同类型实验室"
            obj.canIRes = false
            ishave = true
            let sql = `select *  from laboratory where laboratoryId in (select  laboratoryId from timeoption where timeId in (select timeOpId from daytime where timeId = ?))`
            let labInfo = await mysql.query(sql,[obj.timeId])
            obj.labInfo = labInfo[0]
          }
        }
        if (ishave) {
          return obj
        } else {
          obj.message = "当前无其他个人预约未约满实验室"
          obj.canIRes = true
          obj.timeId = null
          return obj
        }
      } else {
        obj.message = "课堂预约无需判断"
        obj.canIRes = true
        obj.timeId = null
        return obj
      }


    } else {
      obj.message = "已经预约无需判断"
      obj.canIRes = true
      obj.timeId = null
      return obj
    }
  }
  // 取消预约
  async cancleRes(reservationId, status) {

    reservationId = parseInt(reservationId)
    let { mysql } = this.app
        //  获取要取消的预约的类型
        let resInfo = await mysql.get('reservation',{reservationId})
        let type = resInfo.type
    let options = {
      where: {
        reservationId
      }
    }

    let res = await mysql.update('reservation', { status: 4 }, options)
          // 通过reservationId查到预约时间段的信息
          let sql = 'select * from daytime where timeId in(select dayTimeId from reservation where reservationId = ?)'
          let timeInfo = await mysql.query(sql, [reservationId])
          let timeId = timeInfo[0].timeId
          let tVolume = timeInfo[0].tVolume
          let nowCount = timeInfo[0].nowCount
          let baseVolume = timeInfo[0].baseVolume
      if(type==0){
        // 取消课堂预约，就直接还原daytime的0状态
        let sql = 'update daytime set tStatus = ? ,nowCount=? where timeId = ?'
        let res = await mysql.query(sql, [0,0,timeId])

      }

    if (res.affectedRows == 1 && type ==1) {


      let options1 = {
        where: {
          timeId
        }
      }
      // 如果是已通过审核的取消
      if (status == 2) {
        // 相应的可预约时间段的剩余空间也要+1
        tVolume = tVolume + 1
        if(tVolume==baseVolume&&nowCount==0){
          let sql = 'update daytime set tStatus = ? where timeId = ?'
          let res = await mysql.query(sql, [0,timeId])
        }
        let res1 = await mysql.update('daytime', { tVolume}, options1)
      } else if (status == 1) {
   
        nowCount = nowCount - 1
          // 如果取消预约后，所有数据恢复原状，那就恢复为暂无预约
      if(tVolume==baseVolume&&nowCount==0){
  
        let sql = 'update daytime set tStatus = ? where timeId = ?'
        let res = await mysql.query(sql, [0,timeId])
        
      }
        let res1 = await mysql.update('daytime', { nowCount }, options1)
      }

    


      
    } 
    return "取消成功"
  }
  // 获取预约详情
  async getResDetail(reservationId) {
    let { mysql } = this.app
    let totalInfo = {}
    // 先获取基础信息
    let baseInfo = await mysql.get('reservation', { reservationId })
    if (baseInfo) {

      totalInfo = { ...baseInfo }
      let userId = baseInfo.userId
      let dayTimeId = baseInfo.dayTimeId
      // 获取到用户信息
      // 用户账号信息
      let accountInfo = await mysql.get('user', { userId })
      let obj = {}
      obj.userId = accountInfo.userId
      obj.account = accountInfo.account
      obj.nickName = accountInfo.nickName
      obj.avatar = accountInfo.avatar
      obj.roleId = accountInfo.roleId
      obj.mobile = accountInfo.mobile
      totalInfo.accountInfo = obj
      let roleId = accountInfo.roleId
      // 用户基本信息
      if (roleId == 1) {
        let teacher = await mysql.get('teacher', { teacherId: userId })
        // baseUser.name = teachName
        totalInfo.userName = teacher.teachName

      } else if (roleId == 2) {
        let student = await mysql.get('student', { studentId: userId })
        totalInfo.userName = student.stuName
      }
      // 获取时间信息
      // 获取预约时间段信息
      let timeInfo = await mysql.get('daytime', { timeId: dayTimeId })
      let timeOpId = timeInfo.timeOpId
      totalInfo.timeInfo = timeInfo
      // 获取预约的具体时间段
      let timeOption = await mysql.get('timeoption', { timeId: timeOpId })
      let laboratoryId = timeOption.laboratoryId
      totalInfo.timeOption = timeOption
      // 获取实验室信息
      let labInfo = await mysql.get('laboratory', { laboratoryId })
      totalInfo.labInfo = labInfo
      // console.log(totalInfo);
      totalInfo.message = "获取成功"
      return totalInfo
    } else {
      totalInfo.message = "该预约记录不存在"
      return totalInfo
    }

  }
  // 审核预约
  async checkRes(reservationId, rejectReason, checkStatus) {
    let { mysql } = this.app
    // 获取当前预约时间段的基本信息
    let sql = 'select * from daytime where timeId in(select dayTimeId from reservation where reservationId = ?)'
    let timeInfo = await mysql.query(sql, [reservationId])
    let timeId = timeInfo[0].timeId
    let tVolume = timeInfo[0].tVolume
    let nowCount = timeInfo[0].nowCount
    let baseVolume = timeInfo[0].baseVolume
    let type = timeInfo[0].type
    if (checkStatus == 0) {
      // 通过 更新预约状态
      let options = {
        where: {
          reservationId
        }
      }
      let res = await mysql.update('reservation', { status: 2 }, options)
      if (res.affectedRows == 1) {
        // 个人预约会减容量
        if(type==1){
        // 审核通过，相应的时间段的容量要-1
        tVolume = tVolume - 1
        nowCount = nowCount - 1
        let options = {
          where: {
            timeId
          }
        }
        await mysql.update("daytime", { tVolume,nowCount }, options)
        }

        return "审核成功"
      } else {
        return "审核失败"
      }
    } else if (checkStatus == 1) {
      let options = {
        where: {
          reservationId
        }
      }
      // 不通过
      let res = await mysql.update('reservation', { rejectReason, status: 5 }, options)
      if (res.affectedRows == 1) {
        // 审核不通过，相应的时间段的申请人数要 -1
        nowCount = nowCount - 1
        let options = {
          where: {
            timeId
          }
        }
        if(nowCount==0&&tVolume==baseVolume){

          let sql = 'update daytime set tStatus = ? where timeId = ?'
          let res = await mysql.query(sql, [0,timeId])
        }
        await mysql.update("daytime", { nowCount }, options)
        return "审核成功"
      } else {
        return "审核失败"
      }
    }
  }
  //  条件获取预约列表
  async getResList(dateTime,status,type,isExamine,labName,reservationId){
    let {mysql} = this.app
    let obj = {}


    function ReturnList(arr,list){
      let arr1 = [...arr]
      let arr2 = []
      let totalList = []
      let count = 0
      let obj = {}
      arr1.forEach((item,index)=>{
        let key = Object.keys(item)[0]
        let value = Object.values(item)[0]

        if(!value||value===undefined||value===""){
         
        }else{
          arr2.push(item)
        }

      })

      // 开始过滤
      if(arr2.length==0){
          //  一个都不传，就原封返回
          obj.list = list
          obj.total=list.length
          return obj
      }else{
        let arr3 = []
        list.forEach((item,index)=>{
            item.isYou = true
          arr2.forEach((item1,index1)=>{
            let key = Object.keys(item1)[0]
            let value = Object.values(item1)[0]
            if(item[key]!=value){
              item.isYou = false
            }
          })
        })
        let arr4 = []
         list.forEach((item,index)=>{
          if(item.isYou){
            arr4.push(item)
            count++
          }
      })
      obj.list = [...arr4]
      obj.total = count
    
      return obj
      }
    }
        // 如果存在日期
        if(dateTime){
          let sql = `select  * from reservation where daytimeId in (select timeId from daytime where dateTime = ?)`
          let list1 = await mysql.query(sql,[dateTime])
          obj =  ReturnList([{status},{type},{isExamine}],list1)
          let arr = [...obj.list]
          for(let i=0; i<arr.length;i++){
              let sql1 = `select datetime from daytime where timeId = ?`
              let resDateTime = await mysql.query(sql1,[arr[i].dayTimeId])
             arr[i].dateTime = resDateTime[0].datetime
              let sql2 = `select * from timeoption where timeId in (select timeOpId from daytime where timeId in (select dayTimeId from reservation where reservationId=?))`
              let resTimeOp = await mysql.query(sql2,[arr[i].reservationId])
              arr[i].timeOption = resTimeOp[0]
              let sql3 = `select * from laboratory where laboratoryId in (select laboratoryId from  timeoption where timeId in (select timeOpId from daytime where timeId = ?  ) )`
              let  resLab = await mysql.query(sql3,[arr[i].dayTimeId])
              arr[i].lab = resLab[0]
          }
          return obj
         
       }else{
        let sql = `select * from reservation`
        let list1 = await mysql.query(sql)
        obj = ReturnList([{status},{type},{isExamine}],list1)
        let arr = [...obj.list]
        for(let i=0; i<arr.length;i++){
            let sql1 = `select datetime from daytime where timeId = ?`
            let resDateTime = await mysql.query(sql1,[arr[i].dayTimeId])
           arr[i].dateTime = resDateTime[0].datetime
            let sql2 = `select * from timeoption where timeId in (select timeOpId from daytime where timeId in (select dayTimeId from reservation where reservationId=?))`
            let resTimeOp = await mysql.query(sql2,[arr[i].reservationId])
            arr[i].timeOption = resTimeOp[0]
            let sql3 = `select * from laboratory where laboratoryId in (select laboratoryId from  timeoption where timeId in (select timeOpId from daytime where timeId = ?  ) )`
            let  resLab = await mysql.query(sql3,[arr[i].dayTimeId])
            arr[i].lab = resLab[0]
        }
        let list = [...arr]
        if(labName){
          let arr1=[]
          list.forEach((item,index)=>{
            let str = item.lab.labName
            if(str.includes(labName)){
              arr1.push(item)
            }
          })
          obj.list = [...arr1]
          obj.total = arr1.length
        }

        if(reservationId){
          reservationId = parseInt(reservationId)
          let arr1=[]
           list.forEach((item,index)=>{

            if(item.reservationId==reservationId){
              arr1.push(item)
            }
          })
          obj.list = [...arr1]
          obj.total = arr1.length
        }

        
        
        return obj
       }
      

  }
}


module.exports = ReservationService